package com.hup.joystick.constant;


import com.hup.joystick.config.AppConfig;
import com.hup.joystick.model.joystick.StandardKey;
import com.hup.joystick.service.jna.DIJoyState2;

import java.util.ArrayList;

/**
 * @author hugan
 * @date 2020/10/20
 */
public class DeviceKey {

    /**
     * 按键类型
     */
    public static class KeyType {
        /**
         * 按钮
         */
        public static final int BTN = 0;
        /**
         * 方向键
         */
        public static final int ARROW = 1;
        /**
         * 摇杆
         */
        public static final int STICK = 2;
    }

    /**
     * 按键操作类型
     */
    public static class KeyActionType {
        /**
         * 按下
         */
        public static final int TYPE_PRESSED = 0;
        /**
         * 抬起
         */
        public static final int TYPE_RELEASED = 1;
        /**
         * 长按(首次按下到抬起的时间内,按固定频率发送的长按事件)
         */
        public static final int TYPE_LONG_PRESSED = 2;
    }

    /**
     * 原始按键定义类:
     * .定义唯一的按键字符
     * .其他原始值,或对应关系
     */
    public static class NativeKeys {
        public static final String[] X = {"X轴-", "X轴+"};
        public static final String[] Y = {"Y轴-", "Y轴+"};
        public static final String[] Z = {"Z轴-", "Z轴+"};
        public static final String[] RX = {"RX轴-", "RX轴+"};
        public static final String[] RY = {"RY轴-", "RY轴+"};
        public static final String[] RZ = {"RZ轴-", "RZ轴+"};
        /**
         * 手柄暂无,不命名
         */
        public static final String[] SLIDER = {"slider0", "slider1"};
        public static final String[] VX = {"VX轴-", "VX轴+"};
        public static final String[] VY = {"VY轴-", "VY轴+"};
        public static final String[] VZ = {"VZ轴-", "VZ轴+"};
        public static final String[] VRX = {"VRX轴-", "VRX轴+"};
        public static final String[] VRY = {"VRY轴-", "VRY轴+"};
        public static final String[] VRZ = {"VRZ轴-", "VRZ轴+"};
        public static final String[] V_SLIDER = {"VSlider0", "VSlider1"};
        public static final String[] AX = {"AX轴-", "AX轴+"};
        public static final String[] AY = {"AY轴-", "AY轴+"};
        public static final String[] AZ = {"AZ轴-", "AZ轴+"};
        public static final String[] ARX = {"ARX轴-", "ARX轴+"};
        public static final String[] ARY = {"ARY轴-", "ARY轴+"};
        public static final String[] ARZ = {"ARZ轴-", "ARZ轴+"};
        public static final String[] A_SLIDER = {"ASlider0", "ASlider1"};
        public static final String[] FX = {"FX轴-", "FX轴+"};
        public static final String[] FY = {"FY轴-", "FY轴+"};
        public static final String[] FZ = {"FZ轴-", "FZ轴+"};
        public static final String[] FRX = {"FRX轴-", "FRX轴+"};
        public static final String[] FRY = {"FRY轴-", "FRY轴+"};
        public static final String[] FRZ = {"FRZ轴-", "FRZ轴+"};
        public static final String[] F_SLIDER = {"FSlider0", "FSlider1"};

        /**
         * 十字方向键的默认值
         */
        public static final int ARROW_DEF_VALUE = 0xFFFFFFFF;
        /**
         * 方向键的值
         */
        public static final int[] ARROW_VALUE = {0, 4500, 9000, 13500, 18000, 22500, 27000, 31500};
        /**
         * 方向键的字符, {@link #getArrowKey(int, int)}
         */
        private static final String[] ARROW = {"上", "右上", "右", "右下", "下", "左下", "左", "左上"};

        /**
         * 缓存的前n个button的字符串, {@link #getButtonKey(int)}
         */
        private static final String[] SHORT_BUTTON = new String[20];

        static {
            for (int i = 0; i < SHORT_BUTTON.length; i++) SHORT_BUTTON[i] = "按钮" + (i + 1);
        }

        /**
         * {@link DIJoyState2#rgdwPOV}转key
         *
         * @param fieldIndex 数组index
         * @return 格式[n方向], 如[1左上]
         */
        public static String getArrowKey(int nativeValue, int fieldIndex) {
            int index = -1;
            for (int i = 0, length = ARROW_VALUE.length; i < length; i++) {
                if (ARROW_VALUE[i] == nativeValue) {
                    index = i;
                    break;
                }
            }
            if (index == -1) return fieldIndex + "未知方向:" + nativeValue;
            return fieldIndex + ARROW[index];
        }

        /**
         * {@link DIJoyState2#rgbButtons}转key
         *
         * @param btnIndex 数组index
         * @return 格式[按钮n], n起始于1, 如[按钮8]
         */
        public static String getButtonKey(int btnIndex) {
            return btnIndex < SHORT_BUTTON.length ? SHORT_BUTTON[btnIndex] : ("按钮" + (btnIndex + 1));
        }
    }

    /**
     * 标准按键
     */
    public static class StandardKeys {
        public static final StandardKey A = StandardKey.button("A");
        public static final StandardKey B = StandardKey.button("B");
        public static final StandardKey X = StandardKey.button("X");
        public static final StandardKey Y = StandardKey.button("Y");
        public static final StandardKey L1 = StandardKey.button("L1");
        public static final StandardKey R1 = StandardKey.button("R1");
        public static final StandardKey L2 = StandardKey.button("L2");
        public static final StandardKey R2 = StandardKey.button("R2");
        public static final StandardKey L3 = StandardKey.button("L3");//按下摇杆的键
        public static final StandardKey R3 = StandardKey.button("R3");
        public static final StandardKey SELECT = StandardKey.button("SELECT");
        public static final StandardKey START = StandardKey.button("START");

        private static final ArrayList<StandardKey> STANDARD_ARROWS = new ArrayList<>(8);
        public static final StandardKey ARROW_N = addArrow(StandardKey.arrow("上"));
        public static final StandardKey ARROW_EN = addArrow(StandardKey.arrow("右上"));
        public static final StandardKey ARROW_E = addArrow(StandardKey.arrow("右"));
        public static final StandardKey ARROW_ES = addArrow(StandardKey.arrow("右下"));
        public static final StandardKey ARROW_S = addArrow(StandardKey.arrow("下"));
        public static final StandardKey ARROW_WS = addArrow(StandardKey.arrow("左下"));
        public static final StandardKey ARROW_W = addArrow(StandardKey.arrow("左"));
        public static final StandardKey ARROW_WN = addArrow(StandardKey.arrow("左上"));

        public static final StandardKey STICK_L_UP = StandardKey.stick("摇杆L上", AppConfig.STICK_RANGE);
        public static final StandardKey STICK_L_RIGHT = StandardKey.stick("摇杆L右", AppConfig.STICK_RANGE);
        public static final StandardKey STICK_L_DOWN = StandardKey.stick("摇杆L下", AppConfig.STICK_RANGE);
        public static final StandardKey STICK_L_LEFT = StandardKey.stick("摇杆L左", AppConfig.STICK_RANGE);
        public static final StandardKey STICK_R_UP = StandardKey.stick("摇杆R上", AppConfig.STICK_RANGE);
        public static final StandardKey STICK_R_RIGHT = StandardKey.stick("摇杆R右", AppConfig.STICK_RANGE);
        public static final StandardKey STICK_R_DOWN = StandardKey.stick("摇杆R下", AppConfig.STICK_RANGE);
        public static final StandardKey STICK_R_LEFT = StandardKey.stick("摇杆R左", AppConfig.STICK_RANGE);

        //下面字段是设置界面使用的
        public static final StandardKey BINDING_ARROW = StandardKey.arrow("方向键");
        public static final StandardKey BINDING_STICK_LX = StandardKey.stick("左摇杆X", AppConfig.STICK_RANGE);
        public static final StandardKey BINDING_STICK_LY = StandardKey.stick("左摇杆Y", AppConfig.STICK_RANGE);
        public static final StandardKey BINDING_STICK_RX = StandardKey.stick("右摇杆X", AppConfig.STICK_RANGE);
        public static final StandardKey BINDING_STICK_RY = StandardKey.stick("右摇杆Y", AppConfig.STICK_RANGE);


        private static StandardKey addArrow(StandardKey key) {
            STANDARD_ARROWS.add(key);
            return key;
        }

        /**
         * 获取标准方向键
         */
        public static StandardKey getArrow(int nativeValue) {
            int index = -1;
            for (int i = 0, length = NativeKeys.ARROW_VALUE.length; i < length; i++) {
                if (NativeKeys.ARROW_VALUE[i] == nativeValue) {
                    index = i;
                    break;
                }
            }
            if (index == -1) return null;
            return STANDARD_ARROWS.get(index);
        }

        public static boolean isArrow(String key) {
            for (StandardKey standardArrow : STANDARD_ARROWS) {
                if (standardArrow.key.equals(key)) return true;
            }
            return false;
        }

        public static boolean isStick(String key) {
            return  (key.startsWith("摇杆"));
        }

        /**
         * 获取标准摇杆
         * @param isLeftStick true-左摇杆
         * @param isX true-X轴,false-Y轴
         */
        public static StandardKey getStick(boolean isLeftStick, boolean isX, long nativeValue) {
            if (isLeftStick) {
                if (isX) {
                    return StandardKey.stick(nativeValue < 0 ? STICK_L_LEFT.key : STICK_L_RIGHT.key, nativeValue);
                } else {
                    return StandardKey.stick(nativeValue < 0 ? STICK_L_UP.key : STICK_L_DOWN.key, nativeValue);
                }
            } else {
                if (isX) {
                    return StandardKey.stick(nativeValue < 0 ? STICK_R_LEFT.key : STICK_R_RIGHT.key, nativeValue);
                } else {
                    return StandardKey.stick(nativeValue < 0 ? STICK_R_UP.key : STICK_R_DOWN.key, nativeValue);
                }
            }
        }

    }

}
